#+TITLE: Manejo de Múltiples Versiones de Python con PYENV
#+AUTHOR: Edison Ibáñez
#+EMAIL: arkhan@disroot.org
#+DATE: 2019-07-27
#+LANGUAGE: es
#+DESCRIPTION: Manejo de Múltiples Versiones de Python con PYENV
#+OPTIONS: num:t toc:nil ::t |:t ^:{} -:t f:t *:t <:t
#+OPTIONS: tex:t d:nil todo:t pri:nil tags:nil
#+OPTIONS: timestamp:t
#+PROPERTY: header-args :eval never-export

* Pyenv
#+attr_org: :width 1200
[[file:img/Getting-Started-With-pyenv_Watermarked.jpg]]
* ¿Por qué usar pyenv?
** ¿Por qué no utilizar la versión de Python del sistema?
Si usas GNU/Linux o Mac ya tienes una versión de Python disponible
- No siempre es la ultima versión ya sea de Python2 o Python3
- No se puede tener diferentes versión de Python2 o Python3
- No se puede probar las novedades o características de la ultima versión de
  Python

#+NAME: Ruta del binario de Python
#+BEGIN_SRC shell  :results outputs raw
which python
#+END_SRC

#+NAME: Version de Python Disponible
#+BEGIN_SRC shell :results outputs raw
python -V
#+END_SRC

Para instalar una librería se debe usar ~sudo pip install pkg~, esto puede
resultar problemático si otro usuario necesita una versión diferente del mismo
paquete.

** ¿Qué pasa con un administrador de paquetes?
Si usar ~sudo pip~ puede resultar problemático lo mas lógico es usar el gestor
de paquetes de nuestro sistema operativo ~apt, yum, zipper, pacman, apk, etc.~
Pero esto también puede llegar a ser in problema debido a la versión de los
paquetes que están disponibles en los repositorios oficiales.

Tomando en cuenta lo antes mencionado que estamos buscando al tratar de
gestionar diferentes versiones de Python.
- Instalar Python en $HOME de cada usuario
- Instalar múltiples versiones de Python
- Especifique la versión exacta de Python que desea
- Cambiar entre las versiones instaladas

* Instalar pyenv
** Dependencias
~pyenv~ compila cada versión desde el código o fuentes por lo que es necesario
tener todas las dependencias necesarias en neutro sistema, esta información se
la puede encontrar en la [[https://devguide.python.org/setup/#build-dependencies][Documentación oficial de Python.]]

*** Ubuntu/Debian
#+BEGIN_SRC shell :results outputs raw
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \
libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl
#+END_SRC

*** Fedora/CentOS/RHEL
#+BEGIN_SRC shell :results outputs raw
sudo yum install zlib-devel bzip2 bzip2-devel readline-devel sqlite \
sqlite-devel openssl-devel xz xz-devel libffi-devel
#+END_SRC
*** openSUSE
#+BEGIN_SRC shell :results outputs raw
zypper in zlib-devel bzip2 libbz2-devel libffi-devel \
libopenssl-devel readline-devel sqlite3 sqlite3-devel xz xz-devel
#+END_SRC
*** Alpine
#+BEGIN_SRC shell :results outputs raw
apk add libffi-dev ncurses-dev openssl-dev readline-dev \
tk-dev xz-dev zlib-dev
#+END_SRC
*** MS Windows
~pyenv~ originalmente no tiene soporte para *MS Windows*, sin embargo existe un
proyecto que llego esta herramienta al sistema de la ventana y se puede
encontrar en el siguiente enlace: [[https://github.com/pyenv-win/pyenv-win]]
** Instalación
*** Usando el Gestor de Paquetes.
En lagunas distribuciones GNU/Linix se puede encontrar un paquete oficial de
~pyenv~ por lo que la instalación se la puede hacer usando el gestor de paquetes
de nuestro sistema (apt, yum, zipper, apk o pacman).
*** pyenv-installer
Podemos hacer uso del instalador con el siguiente comando.
#+BEGIN_SRC shell :results outputs raw
curl https://pyenv.run | bash
#+END_SRC
Dependiendo del método de instalación tendremos disponibles los siguientes
complementos:
- pyenv: La aplicación de ~pyenv~
- pyenv-virtualenv: Complemento para gestionar entornos virtuales
- pyenv-update: Complemento para actualizar ~pyenv~
- pyenv-doctor: Complemento para verificar que ~pyenv~ y sus dependencias se
  encuentran instaladas
- pyenv-which-ext: Complemento para buscar automáticamente los comandos del
  sistema.

Ahora nos falta cargar de forma automáticamente ~pyenv~
#+BEGIN_SRC shell :results outputs raw
# Load pyenv automatically by adding
# the following to ~/.bashrc:

export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
#+END_SRC

* Usar pyenv pata Instalar Python
Ahora que ya tenemos disponible y cargado ~pyenv~ en nuestro sistema podremos
empezar a instalar la versión de Python que necesitemos.

: Listar las versiones disponibles de Python 2
#+BEGIN_SRC shell :results outputs raw
pyenv install --list | grep " 2\.[678]"
#+END_SRC

#+NAME: Listar las versiones disponibles de Python 3
#+BEGIN_SRC shell :results outputs raw
pyenv install --list | grep " 3\.[678]"
#+END_SRC

#+NAME: Listar las versiones disponibles de Jython
#+BEGIN_SRC shell :results outputs raw
pyenv install --list | grep "jython"
#+END_SRC

#+NAME: Listar todas las versiones disponibles de python
#+BEGIN_SRC shell :results outputs raw
pyenv install --list
#+END_SRC

#+NAME: Instalar Python 3.7.1
#+BEGIN_SRC shell :async :results outputs raw
CC=clang pyenv install -v 3.7.1
#+END_SRC

Si se encuentra algún problema durante la instalación se puede consultar el
siguiente enlace [[https://github.com/pyenv/pyenv/wiki/Common-build-problems]]

** Ubicación de la Instalación
Como se menciono anterior ~pyenv~ trabaja con el código fuente de cada versión
de Python se encenta en la siguiente ubicación.
#+BEGIN_SRC shell :results outputs raw
ls -l ~/.pyenv/versions/
#+END_SRC

Para eliminar una versión instalada se puede simplemente eliminar dicha versión
de la ubicación donde se instalo.
#+BEGIN_SRC shell :results outputs raw
rm -rf ~/.pyenv/versions/3.7.1
#+END_SRC

o ejecutando el comando que ofrece ~pyenv~
#+BEGIN_SRC shell :results outputs raw
pyenv uninstall 3.7.1
#+END_SRC

** Usando nuestra nueva version de Python
Primero debemo comprbar las versiones disponibles.
#+BEGIN_SRC shell :results outputs raw
pyenv versions
#+END_SRC

El simobolo * nos indica que version de python se encontra activa.
Ahora si confirmamos la ruta del binario obtendremos lo siguiente.
#+BEGIN_SRC shell :results outputs raw
which python
#+END_SRC

Si queremos cambiar la version por defecto Python para nuestro usuario podemos
hacerlo de la siguiente manera.
#+BEGIN_SRC shell :results outputs raw
pyenv global 3.7.1
#+END_SRC

Para regresar a la version de nuestro sistema basta con ejecutar.
#+BEGIN_SRC shell :results outputs raw
pyenv global system
#+END_SRC

* Comandos de pyenv
** install
#+BEGIN_SRC shell :results outputs raw
pyenv install 3.7.1
#+END_SRC
** versions
#+BEGIN_SRC shell :results outputs raw
pyenv versions
#+END_SRC
** which
#+BEGIN_SRC shell :results outputs raw
pyenv which pip
#+END_SRC
** global
#+BEGIN_SRC shell :results outputs raw
pyenv global 3.7.1
#+END_SRC
** local
#+BEGIN_SRC shell :results outputs raw
pyenv local 3.7.1
#+END_SRC
** shell
#+BEGIN_SRC shell :results outputs raw
pyenv shell 3.7.1
#+END_SRC
* Especificar una versión de Python
Con ~pyenv~ se puede especificar una Versión de Python para un proyecto, basta
con ir a la carpeta que contiene dicho proyecto y ejecutar.
#+BEGIN_SRC shell :results outputs raw
pyenv local 3.7.1
#+END_SRC

Esto crea un archivo llamado ~.python-version~ que contiene la versión que
especificamos.
Con esto cada vez que trabajemos con ese proyecto estaremos usando la versión de
Python que especificamos con anterioridad.

* Usando Entornos Virtuales con pyenv
** Crear Entornos Virtuales
Podemos tener Varios Entornos Virtaules de Python con una version especifica del
lenguage, usando el subcomando ~virtualenv~ seguido de la version de python y el
nombre del entorno virtual.
#+BEGIN_SRC shell :results outputs raw
pyenv virtualenv <python_version> <virtualenv>
#+END_SRC

#+BEGIN_SRC shell :results outputs raw
pyenv virtualenv 3.7.1 meetup
#+END_SRC
** Activando nuestro Entorno Virtual
Una vez creado el entorno solo nos falta especificar el entorno virtual en
nuestro proyecto.
#+BEGIN_SRC shell :results outputs raw
pyenv local <virtualenv>
#+END_SRC

#+BEGIN_SRC shell :results outputs raw
pyenv local meetup
#+END_SRC

* Enlaces externos
- [[https://realpython.com/intro-to-pyenv]]
- [[https://github.com/pyenv]]
- https://github.com/pyenv/pyenv
